package handlers

import (
	"encoding/json"
	"errors"
	"net/http"
	"strings"

	"go.mongodb.org/mongo-driver/mongo"

	"zwai-app/config"
	"zwai-app/middleware"
	"zwai-app/models"
	"zwai-app/services"
	"zwai-app/util"

	"go.mongodb.org/mongo-driver/bson/primitive"
)

// 新增：只用来接收前端请求
type createArticleReq struct {
	Title       string   `json:"title"`
	Description string   `json:"description"`
	Content     string   `json:"content"`
	Tags        []string `json:"tags"`
	CategoryID  string   `json:"categoryId"` // ← 一定要有
}

// RegisterArticleRoutes 挂载文章相关路由
func RegisterArticleRoutes(mux *http.ServeMux, cfg config.Config) {
	mux.HandleFunc("/articles", middleware.AuthMiddleware(postArticleHandler, cfg))      // POST /articles
	mux.HandleFunc("/articles/approve/", middleware.AuthMiddleware(approveHandler, cfg)) // POST /articles/approve/{id}
	mux.HandleFunc("/articles/reject/", middleware.AuthMiddleware(rejectHandler, cfg))   // POST /articles/reject/{id}
	mux.HandleFunc("/articles/like/", middleware.AuthMiddleware(likeHandler, cfg))       // POST /articles/like/{id}
	mux.HandleFunc("/articles/comments/", func(w http.ResponseWriter, r *http.Request) { // GET/POST /articles/comments/{id}
		commentHandler(w, r, cfg)
	})
	mux.HandleFunc("/articles/", getArticleHandler)                                                   // GET  /articles/{id}
	mux.HandleFunc("/articles/public", publicArticlesHandler)                                         // GET  /articles/public
	mux.HandleFunc("/articles/feed", middleware.AuthMiddleware(feedArticlesHandler, cfg))             // GET  /articles/feed
	mux.HandleFunc("/articles/liked", middleware.AuthMiddleware(likedArticlesHandler, cfg))           // GET  /articles/liked
	mux.HandleFunc("/articles/hot", hotArticlesHandler)                                               // GET  /articles/hot
	mux.HandleFunc("/articles/all", allArticlesHandler)                                               // GET  /articles/all
	mux.HandleFunc("/me/articles", middleware.AuthMiddleware(myArticlesHandler, cfg))                 // GET  /me/articles
	mux.HandleFunc("/articles/visibility/", middleware.AuthMiddleware(updateVisibilityHandler, cfg))  // PUT /articles/visibility/{id}
	mux.HandleFunc("/admin/articles/pending", middleware.AuthMiddleware(pendingArticlesHandler, cfg)) // GET /admin/articles/pending
}

func myArticlesHandler(w http.ResponseWriter, r *http.Request) {
	if r.Method != http.MethodGet {
		util.JSONResponse(w, http.StatusNotFound, map[string]interface{}{"code": 1, "msg": "接口不存在"})
		return
	}
	userID := middleware.FromContext(r)
	list, err := services.GetUserArticles(r.Context(), userID)
	if err != nil {
		util.JSONResponse(w, http.StatusInternalServerError, map[string]interface{}{"code": 2, "msg": "查询失败:" + err.Error()})
		return
	}
	util.JSONResponse(w, http.StatusOK, map[string]interface{}{"code": 0, "msg": "查询成功", "data": list})
}

func updateVisibilityHandler(w http.ResponseWriter, r *http.Request) {
	if r.Method != http.MethodPut {
		util.JSONResponse(w, http.StatusNotFound, map[string]interface{}{"code": 1, "msg": "接口不存在"})
		return
	}
	// URL: /articles/visibility/{id}
	parts := strings.Split(strings.Trim(r.URL.Path, "/"), "/")
	if len(parts) != 3 || parts[0] != "articles" || parts[1] != "visibility" {
		util.JSONResponse(w, http.StatusNotFound, map[string]interface{}{"code": 2, "msg": "接口不存在"})
		return
	}
	idHex := parts[2]
	aid, err := primitive.ObjectIDFromHex(idHex)
	if err != nil {
		util.JSONResponse(w, http.StatusBadRequest, map[string]interface{}{"code": 3, "msg": "文章ID无效"})
		return
	}

	var body struct {
		Visibility string `json:"visibility"`
	}
	if err := json.NewDecoder(r.Body).Decode(&body); err != nil {
		util.JSONResponse(w, http.StatusBadRequest, map[string]interface{}{"code": 4, "msg": "请求解析失败"})
		return
	}

	userIDHex := middleware.FromContext(r)
	uid, _ := primitive.ObjectIDFromHex(userIDHex)
	if err := services.UpdateArticleVisibility(r.Context(), aid, uid, body.Visibility); err != nil {
		if errors.Is(err, services.ErrNotAuthor) {
			util.JSONResponse(w, http.StatusForbidden, map[string]interface{}{"code": 5, "msg": "只有作者本人可修改"})
		} else {
			util.JSONResponse(w, http.StatusInternalServerError, map[string]interface{}{"code": 6, "msg": "更新失败:" + err.Error()})
		}
		return
	}
	util.JSONResponse(w, http.StatusOK, map[string]interface{}{"code": 0, "msg": "更新成功"})
}

// postArticleHandler 处理 POST /articles
func postArticleHandler(w http.ResponseWriter, r *http.Request) {
	if r.Method != http.MethodPost {
		util.JSONResponse(w, http.StatusMethodNotAllowed, map[string]interface{}{
			"code": 1, "msg": "只支持 POST",
		})
		return
	}
	userID := middleware.FromContext(r)
	uid, _ := primitive.ObjectIDFromHex(userID)

	// 1) 解码到自己定义的请求体
	var req createArticleReq
	if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
		util.JSONResponse(w, http.StatusBadRequest, map[string]interface{}{
			"code": 2, "msg": "JSON 解析失败: " + err.Error(),
		})
		return
	}
	// 2) 校验必须传 categoryId
	if strings.TrimSpace(req.CategoryID) == "" {
		util.JSONResponse(w, http.StatusBadRequest, map[string]interface{}{
			"code": 3, "msg": "分类 ID 不能为空",
		})
		return
	}
	catOID, err := primitive.ObjectIDFromHex(req.CategoryID)
	if err != nil {
		util.JSONResponse(w, http.StatusBadRequest, map[string]interface{}{
			"code": 4, "msg": "无效的分类 ID",
		})
		return
	}

	// 3) 手动组装 models.Article，填上分类
	art := models.Article{
		Title:      req.Title,
		Content:    req.Content,
		CategoryID: catOID, // 新增字段
		Tags:       req.Tags,
		// CreateArticle 会帮你填 status、authorId、timestamps
	}

	// 4) 调用服务层
	id, err := services.CreateArticle(r.Context(), uid, &art)
	if err != nil {
		util.JSONResponse(w, http.StatusInternalServerError, map[string]interface{}{
			"code": 5, "msg": "提交失败: " + err.Error(),
		})
		return
	}
	util.JSONResponse(w, http.StatusOK, map[string]interface{}{
		"code": 0, "msg": "提交成功", "data": id.Hex(),
	})
}

// approveHandler 处理 POST /articles/approve/{id}
func approveHandler(w http.ResponseWriter, r *http.Request) {
	if r.Method != http.MethodPost {
		util.JSONResponse(w, http.StatusMethodNotAllowed, map[string]interface{}{"code": 1, "msg": "只支持 POST"})
		return
	}
	parts := strings.Split(strings.Trim(r.URL.Path, "/"), "/")
	if len(parts) < 3 {
		util.JSONResponse(w, http.StatusBadRequest, map[string]interface{}{"code": 2, "msg": "缺少文章ID"})
		return
	}
	idHex := parts[2]
	aid, err := primitive.ObjectIDFromHex(idHex)
	if err != nil {
		util.JSONResponse(w, http.StatusBadRequest, map[string]interface{}{"code": 2, "msg": "文章ID无效"})
		return
	}
	if err := services.ApproveArticle(r.Context(), aid); err != nil {
		util.JSONResponse(w, http.StatusInternalServerError, map[string]interface{}{"code": 3, "msg": "审核通过失败: " + err.Error()})
		return
	}
	util.JSONResponse(w, http.StatusOK, map[string]interface{}{"code": 0, "msg": "审核通过"})
}

// rejectHandler 处理 POST /articles/reject/{id}
func rejectHandler(w http.ResponseWriter, r *http.Request) {
	if r.Method != http.MethodPost {
		util.JSONResponse(w, http.StatusMethodNotAllowed, map[string]interface{}{"code": 1, "msg": "只支持 POST"})
		return
	}
	// 路径 /articles/reject/{id}
	parts := strings.Split(strings.Trim(r.URL.Path, "/"), "/")
	if len(parts) != 3 {
		util.JSONResponse(w, http.StatusBadRequest, map[string]interface{}{"code": 2, "msg": "缺少文章ID"})
		return
	}
	aid, err := primitive.ObjectIDFromHex(parts[2])
	if err != nil {
		util.JSONResponse(w, http.StatusBadRequest, map[string]interface{}{"code": 3, "msg": "文章ID无效"})
		return
	}
	// 解析 body 中的拒绝原因
	var body struct {
		Reason string `json:"reason"`
	}
	if err := json.NewDecoder(r.Body).Decode(&body); err != nil || strings.TrimSpace(body.Reason) == "" {
		util.JSONResponse(w, http.StatusBadRequest, map[string]interface{}{"code": 4, "msg": "请提供拒绝原因"})
		return
	}
	if err := services.RejectArticle(r.Context(), aid, body.Reason); err != nil {
		util.JSONResponse(w, http.StatusInternalServerError, map[string]interface{}{"code": 5, "msg": "拒绝失败: " + err.Error()})
		return
	}
	util.JSONResponse(w, http.StatusOK, map[string]interface{}{"code": 0, "msg": "已拒绝"})
}

// getArticleHandler 处理 GET /articles/{id}
func getArticleHandler(w http.ResponseWriter, r *http.Request) {
	if r.Method != http.MethodGet {
		util.JSONResponse(w, http.StatusMethodNotAllowed, map[string]interface{}{"code": 1, "msg": "只支持 GET"})
		return
	}
	parts := strings.Split(strings.Trim(r.URL.Path, "/"), "/")
	if len(parts) != 2 || parts[0] != "articles" {
		util.JSONResponse(w, http.StatusBadRequest, map[string]interface{}{"code": 2, "msg": "接口不存在"})
		return
	}
	idHex := parts[1]

	art, err := services.GetArticleDetails(r.Context(), idHex)
	if err != nil {
		if err == mongo.ErrNoDocuments {
			util.JSONResponse(w, http.StatusNotFound, map[string]interface{}{"code": 3, "msg": "文章未找到"})
		} else {
			util.JSONResponse(w, http.StatusInternalServerError, map[string]interface{}{"code": 4, "msg": "获取失败: " + err.Error()})
		}
		return
	}
	util.JSONResponse(w, http.StatusOK, map[string]interface{}{"code": 0, "msg": "查询成功", "data": art})
}

// likeHandler 处理 POST /articles/like/{id}
func likeHandler(w http.ResponseWriter, r *http.Request) {
	if r.Method != http.MethodPost {
		util.JSONResponse(w, http.StatusMethodNotAllowed, map[string]interface{}{"code": 1, "msg": "只支持 POST"})
		return
	}
	parts := strings.Split(strings.Trim(r.URL.Path, "/"), "/")
	if len(parts) < 3 {
		util.JSONResponse(w, http.StatusBadRequest, map[string]interface{}{"code": 2, "msg": "缺少文章ID"})
		return
	}
	idHex := parts[2]
	aid, err := primitive.ObjectIDFromHex(idHex)
	if err != nil {
		util.JSONResponse(w, http.StatusBadRequest, map[string]interface{}{"code": 2, "msg": "文章ID无效"})
		return
	}
	userID := middleware.FromContext(r)
	uid, _ := primitive.ObjectIDFromHex(userID)
	if err := services.LikeArticle(r.Context(), aid, uid); err != nil {
		util.JSONResponse(w, http.StatusInternalServerError, map[string]interface{}{"code": 3, "msg": "操作失败: " + err.Error()})
		return
	}
	util.JSONResponse(w, http.StatusOK, map[string]interface{}{"code": 0, "msg": "操作成功"})
}

// commentHandler 处理 POST /articles/comments/{id}
// 拆成真正的 handler，带上 cfg
func commentHandler(w http.ResponseWriter, r *http.Request, cfg config.Config) {
	// 解析 /articles/comments/{articleId}
	parts := strings.Split(strings.Trim(r.URL.Path, "/"), "/")
	if len(parts) != 3 || parts[0] != "articles" || parts[1] != "comments" {
		util.JSONResponse(w, http.StatusNotFound, map[string]interface{}{"code": 1, "msg": "接口不存在"})
		return
	}
	articleIDHex := parts[2]

	switch r.Method {
	case http.MethodGet:
		// —— GET: 公开接口 ——
		list, err := services.GetCommentsFlat(r.Context(), articleIDHex)
		if err != nil {
			util.JSONResponse(w, http.StatusInternalServerError, map[string]interface{}{
				"code": 2, "msg": "查询失败: " + err.Error(),
			})
			return
		}
		util.JSONResponse(w, http.StatusOK, map[string]interface{}{
			"code": 0, "msg": "查询成功", "data": list,
		})

	case http.MethodPost:
		// —— POST: 需要鉴权 ——
		auth := r.Header.Get("Authorization")
		if !strings.HasPrefix(auth, "Bearer ") {
			util.JSONResponse(w, http.StatusUnauthorized, map[string]interface{}{"code": 3, "msg": "请先登录"})
			return
		}
		token := strings.TrimPrefix(auth, "Bearer ")
		userIDHex, err := services.ValidateToken(token, cfg)
		if err != nil {
			util.JSONResponse(w, http.StatusUnauthorized, map[string]interface{}{"code": 3, "msg": "请先登录"})
			return
		}

		// 解析 body
		var req struct {
			Content  string  `json:"content"`
			ParentID *string `json:"parentId,omitempty"`
		}
		if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
			util.JSONResponse(w, http.StatusBadRequest, map[string]interface{}{"code": 4, "msg": "请求解析失败"})
			return
		}
		aid, err := primitive.ObjectIDFromHex(articleIDHex)
		if err != nil {
			util.JSONResponse(w, http.StatusBadRequest, map[string]interface{}{"code": 5, "msg": "文章ID无效"})
			return
		}
		uid, err := primitive.ObjectIDFromHex(userIDHex)
		if err != nil {
			util.JSONResponse(w, http.StatusInternalServerError, map[string]interface{}{"code": 6, "msg": "内部错误"})
			return
		}

		comment := models.Comment{
			ArticleID: aid,
			AuthorID:  uid,
			Content:   req.Content,
		}
		if req.ParentID != nil {
			if pid, err := primitive.ObjectIDFromHex(*req.ParentID); err == nil {
				comment.ParentID = &pid
			}
		}
		cid, err := services.AddComment(r.Context(), &comment)
		if err != nil {
			util.JSONResponse(w, http.StatusInternalServerError, map[string]interface{}{"code": 7, "msg": "发表评论失败: " + err.Error()})
			return
		}
		util.JSONResponse(w, http.StatusOK, map[string]interface{}{"code": 0, "msg": "评论成功", "data": cid.Hex()})

	default:
		util.JSONResponse(w, http.StatusMethodNotAllowed, map[string]interface{}{"code": 8, "msg": "只支持 GET 和 POST"})
	}
}

// Handler 实现：

func feedArticlesHandler(w http.ResponseWriter, r *http.Request) {
	if r.Method != http.MethodGet {
		util.JSONResponse(w, http.StatusNotFound, map[string]interface{}{"code": 1, "msg": "接口不存在"})
		return
	}
	userID := middleware.FromContext(r)
	list, err := services.GetFeedArticles(r.Context(), userID)
	if err != nil {
		util.JSONResponse(w, http.StatusInternalServerError, map[string]interface{}{"code": 2, "msg": "查询失败:" + err.Error()})
		return
	}
	util.JSONResponse(w, http.StatusOK, map[string]interface{}{"code": 0, "msg": "查询成功", "data": list})
}

func likedArticlesHandler(w http.ResponseWriter, r *http.Request) {
	if r.Method != http.MethodGet {
		util.JSONResponse(w, http.StatusNotFound, map[string]interface{}{"code": 1, "msg": "接口不存在"})
		return
	}
	userID := middleware.FromContext(r)
	list, err := services.GetLikedArticles(r.Context(), userID)
	if err != nil {
		util.JSONResponse(w, http.StatusInternalServerError, map[string]interface{}{"code": 2, "msg": "查询失败:" + err.Error()})
		return
	}
	util.JSONResponse(w, http.StatusOK, map[string]interface{}{"code": 0, "msg": "查询成功", "data": list})
}

func pendingArticlesHandler(w http.ResponseWriter, r *http.Request) {
	if r.Method != http.MethodGet {
		util.JSONResponse(w, http.StatusNotFound, map[string]interface{}{"code": 1, "msg": "接口不存在"})
		return
	}
	list, err := services.GetPendingArticles(r.Context())
	if err != nil {
		util.JSONResponse(w, http.StatusInternalServerError, map[string]interface{}{"code": 2, "msg": "查询失败:" + err.Error()})
		return
	}
	util.JSONResponse(w, http.StatusOK, map[string]interface{}{"code": 0, "msg": "查询成功", "data": list})
}
